package org.osomit.sacct.security.otp.impl;

import org.osomit.sacct.security.otp.impl.FileOTPProfileRegistryLoader;
import org.osomit.sacct.security.otp.impl.OTPProfile;
import org.osomit.sacct.security.otp.impl.InMemoryOTPProfileRegistry;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * Test loading and persisting the OTP Profile Registry to and from the file system
 * 
 * @author Jian Fang (John.Jian.Fang@gmail.com)
 *
 * Date: Jun 26, 2009
 */
public class FileOTPProfileRegistryLoader_UT {
	private static String SECRET_STRING1 = "12345678901234567890";
	private static String SECRET_STRING2 = "32345678901234567895";
	private static long initCount = 100;
	private static int codeDigits = 9;
	private static boolean addChecksum = true;
	private static int truncationOffset = 20;
	private static String SN1 = "321151351351";
	private static String SN2 = "321151351352";
	private static String password = "good4you";
	private static int stepSize = 100;
	private static FileOTPProfileRegistryLoader loader;
	private static String FILE_NAME = "OTPProfile.reg";
	private static OTPProfile profile1;
	private static OTPProfile profile2;

	@BeforeClass
	public static void singleSetup() throws Exception{
		loader = new FileOTPProfileRegistryLoader();
		loader.setFileName(FILE_NAME);
		loader.setPassword(password);
		profile1 = new OTPProfile(SN1, SECRET_STRING1.getBytes(), initCount,
				System.currentTimeMillis(), codeDigits, addChecksum, truncationOffset,
				stepSize, 1);
		profile2 = new OTPProfile(SN2, SECRET_STRING2.getBytes(), initCount,
				System.currentTimeMillis(), codeDigits, addChecksum, truncationOffset,
				stepSize, 0);
	}

	@AfterClass
	public static void singleTearDown() {
		profile2 = null;
		profile1 = null;
		loader = null;
	}

	@Test
	public void testPersistRegistry(){
		InMemoryOTPProfileRegistry registry = new InMemoryOTPProfileRegistry();

		registry.addOTPProfile(profile1);
		registry.addOTPProfile(profile2);

		try {
			loader.persist(registry);
		} catch (Exception e) {
			fail(e.getLocalizedMessage());
		}
	}

	@Test
	public void testLoadRegistry(){
		testPersistRegistry();
		InMemoryOTPProfileRegistry registry = new InMemoryOTPProfileRegistry();
		try {
			loader.load(registry);
			OTPProfile p1 = registry.getOTPProfile(profile1.getSN());
			validateOTPProfile(profile1, p1);
			OTPProfile p2 = registry.getOTPProfile(profile2.getSN());
			validateOTPProfile(profile2, p2);
		} catch (Exception e) {
			fail(e.getLocalizedMessage());
		}
	}

	public void validateOTPProfile(OTPProfile p1, OTPProfile p2){
		assertNotNull(p1);
		assertNotNull(p2);
		assertEquals(p1.getSN(), p2.getSN());
		assertEquals(p1.getBias(), p2.getBias());
		assertEquals(p1.getCounter(), p2.getCounter());
		assertEquals(p1.getFailedAttempts(), p2.getFailedAttempts());
		assertEquals(p1.getOtpLength(), p2.getOtpLength());
		assertTrue(new String(p1.getSecret()).equals(new String(p2.getSecret())));
		assertEquals(p1.getStepSize(), p2.getStepSize());
		assertEquals(p1.getTruncationOffset(), p2.getTruncationOffset());
		assertEquals(p1.getClass(), p2.getClass());
	}
}
